---
title: "Theming: Distributing Shared Themes & Parts"
---

For organisations with multiple applications, you can create your own themes and parts to share styles between applications.

### Creating Themes From Scratch

Most applications create themes by starting with a built-in theme like `themeQuartz` and using the `withParams` and `withPart` method to generate a customised version.

The `createTheme` function creates a new theme containing core styles but no parts. If you're going to change most of the parts anyway, starting from a new theme will reduce the bundle size compared to starting with a built-in theme.

```js
import { createTheme, iconSetMaterial } from 'ag-grid-community';

const myCustomTheme = createTheme()
    // add just the parts you want
    .withPart(iconSetMaterial)
    .withPart(colorSchemeVariable)
    // set default param values
    .withParams({
        accentColor: 'red',
        iconSize: 18,
    });
```

Note that the checkboxes in the example below are using the default styles from your web browser, because the parts containing their styles have not been added. This is useful if your application does not contain these features, or if you want a clean base upon which to apply your own checkbox styles.

{% gridExampleRunner title="Creating a Theme From Scratch" name="creating-themes" /%}

### Creating Your Own Parts

For organisations that create a library of reusable styles and share them among many applications, parts can be a convenient way to package up styles and parameters so that each application can use a subset of the whole library.

The benefit of using parts rather than adding CSS in your application stylesheets is that the CSS is scoped: the CSS you provide will only apply to grids with your theme applied, whereas by default CSS in your application stylesheets will apply to all grids unless you add rules to prevent it.

The `createPart` function creates an empty part and takes the following arguments:

```js
import { createPart } from 'ag-grid-community';

const myCheckboxStyle = createPart({
    // By setting the feature, adding this part to a theme will remove the
    // theme's existing checkboxStyle, if any
    feature: 'checkboxStyle',
    params: {
        // Declare parameters added by the custom CSS and provide default values
        checkboxCheckedGlowColor: { ref: 'accentColor' },
        checkboxGlowColor: { ref: 'foregroundColor', mix: 0.5 },
        // If you want to provide new default values for parameters already defined
        // by the grid, you can do so too
        accentColor: 'red',
    },
    // Add some CSS to this part.
    // If your application is bundled with Vite you can put this in a separate
    // file and import it with `import checkboxCSS from "./checkbox.css?inline"`
    css: `
        .ag-checkbox-input-wrapper {
            border-radius: 4px;
            /* Here we're referencing the checkboxGlowColor parameter in CSS, we need
               to add the --ag- prefix and use kebab-case */
            box-shadow: 0 0 5px 4px var(--ag-checkbox-glow-color);

        ... css implementing the new checkbox style ...
        
        `,
});
```

{% gridExampleRunner title="Creating Parts" name="creating-parts" /%}

#### Choosing A Feature For Your Part

You have three options for `feature`:

- `undefined`, or omit the feature property. In this case once added to a theme the part can not be removed. Many applications choose to bundle all the CSS for a custom theme in one part with no feature set. This is the simplest way of getting the CSS scoping benefits of using parts.
- One of the built-in part features, like `checkboxStyle` or `iconSet`. See the [Parts](./theming-parts/) page for a full list. Adding the part to any theme will replace the built-in part with the same feature.
- A string of your choice, in order to use the same part replacement semantics in your own design system. We recommend prefixing the part name with your organisation to prevent name clashes in future grid versions. For example, Acme Corp might have several typography styles, represented as parts with the feature `acmeCorpTypographyStyle`. Your custom theme can bundle a default typography style, and applications can replace it with a different one if they wish.

#### Naming Of Parameters In Custom Parts

Parameters must use a naming convention based on their type, so for example all colour parameters must end with `Color`. The full list of types and suffixes is on the [Parameters](./theming-parameters/) page. Any variable without a recognised suffix is considered to be a length.

Using the correct type suffix ensures that values will be interpreted correctly, allowing you to use the extended syntax, e.g. `{ref: "accentColor", mix: 0.5}` to create a semi-transparent colour.

Additionally, the suffix is used by Typescript to infer the correct type for the parameter, ensuring that applications using the part and overriding the default value in their theme will get appropriate type checking.

### Multiple Grids

Each grid on the page can have its own theme. In the example below, 3 themes are used by 4 grids. The bottom two grids share a theme (Balham) and use CSS custom properties to achieve different header colours:

{% gridExampleRunner title="Multiple Grids" name="multiple-grids" /%}

### Themed grids in Shadow DOM / Web Components

When distributing themed grids, you may want to use [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) (or Web Components, which often use Shadow DOM under the hood) to isolate grid styles from the page.

When using Shadow DOM, the grid inserts the compiled theme CSS into the shadow root rather than the main document. In most cases it can automatically detect the use of Shadow DOM. But there are edge cases, such as when a grid is initialized detached from the DOM, where it can't detect that it's going to be running in a Shadow DOM. In this case the grid will appear unstyled. Use the [`themeStyleContainer` grid option](./grid-options/#reference-theme-themeStyleContainer) to tell the grid where to insert styles.